package cn.wangkai.peanut.db.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DesEncode {
	private static Log logger = LogFactory.getLog(DesEncode.class);

	/**
	 * 对外界提供的加密接口，入口参数就是欲加密的字符串
	 * 
	 * @param baseString
	 * @param filepath
	 *            密钥文件,如果文件不存在,重新生成密钥文件
	 * @return
	 */
	public String encode(String baseString, String filepath) {
		byte[] bytes = null;
		try {
			// 获取字符串加密后的密文字节数组
			bytes = dese(baseString, filepath);
		} catch (Exception e) {
			logger.error("encode key error", e);
		}

		String dbPswd = "";
		for (int i = 0; i < bytes.length; i++) {
			dbPswd += bytes[i] + ",";
		}
		dbPswd = dbPswd.substring(0, dbPswd.length() - 1);

		return dbPswd;
	}

	public String encode(String baseString) {
		return encode(baseString, null);
	}

	/**
	 * 对外界提供的解密接口，入口参数为欲解密的字符串 密文路径在classpath根目录
	 * 
	 * @param encodeStr
	 * @return
	 */
	public String decode(String encodeStr, String filepath) {
		byte[] bytes = null;
		try {
			logger.debug("encodeStr is: " + encodeStr);
			// 获取解密后的明文字节数组
			bytes = unDese(encodeStr, filepath);
		} catch (Exception e) {
			logger.error("decode error", e);
			return "";
		}

		return new String(bytes);
	}

	public String decode(String encodeStr, byte[] bytes) {
		byte[] m = null;
		try {
			// 初始化密钥和解密器
			SecretKeySpec k = new SecretKeySpec(bytes, "DESede");
			Cipher cp = Cipher.getInstance("DESede");

			cp.init(Cipher.DECRYPT_MODE, k);

			String[] encodeS = encodeStr.split(",");
			byte[] bs = new byte[encodeS.length];
			for (int i = 0; i < encodeS.length; i++) {
				bs[i] = Byte.parseByte(encodeS[i].trim());
			}

			// 对字符串进行解密
			m = cp.doFinal(bs);

			logger.debug("m size is: " + m.length);
		} catch (Exception e) {
			logger.error("decode error", e);
			return "";
		}
		return new String(m);
	}

	/**
	 * 进行加密的业务类
	 * 
	 * @param baseStr
	 * @param filepath
	 *            : 密钥文件,如果文件不存在,重新生成密钥
	 * @return
	 * @throws Exception
	 */
	private byte[] dese(String baseStr, String filepath) throws Exception {
		SecretKey k = null;
		File f = new File(filepath);
		if (!f.exists()) {
			// 获取密钥生成器
			KeyGenerator kg = KeyGenerator.getInstance("DESede");
			kg.init(168);
			// 生成密钥
			k = kg.generateKey();
			FileOutputStream fout = new FileOutputStream(filepath);
			fout.write(k.getEncoded());
			fout.close();
		} else {
			FileInputStream fin = new FileInputStream(filepath);
			f = new File(filepath);
			byte[] bytes = new byte[(int) f.length()];
			fin.read(bytes);
			fin.close();
			// 初始化密钥和解密器
			k = new SecretKeySpec(bytes, "DESede");
		}
		// 获取加密器
		Cipher cp = Cipher.getInstance("DESede");
		cp.init(Cipher.ENCRYPT_MODE, k);

		// 以文件形式保存密钥
		// String classPath = getClassPath();

		byte[] bytes = baseStr.getBytes();

		// 对字符串进行加密
		byte cb[] = cp.doFinal(bytes);

		return cb;
	}

	/**
	 * 进行解密的业务类
	 * 
	 * @param encodeStr
	 * @return
	 * @throws Exception
	 */
	private byte[] unDese(String encodeStr, String filepath) throws Exception {
		// 读取密钥
		FileInputStream fin = new FileInputStream(filepath);
		File f = new File(filepath);

		byte[] bytes = new byte[(int) f.length()];
		fin.read(bytes);
		fin.close();

		// 初始化密钥和解密器
		SecretKeySpec k = new SecretKeySpec(bytes, "DESede");
		Cipher cp = Cipher.getInstance("DESede");

		cp.init(Cipher.DECRYPT_MODE, k);

		String[] encodeS = encodeStr.split(",");
		byte[] bs = new byte[encodeS.length];
		for (int i = 0; i < encodeS.length; i++) {
			bs[i] = Byte.parseByte(encodeS[i].trim());
		}

		// 对字符串进行解密
		byte[] m = cp.doFinal(bs);

		//logger.debug("m size is: " + m.length);
		return m;
	}

//	/**
//	 * 取jdbc.DESede文件路径
//	 * 
//	 * @return
//	 */
//	private String getClassPath() {
//		String classPath = this.getClass().getResource("/").getPath();
//		File file = new File(classPath);
//		if (file.exists())
//			classPath = file.getParentFile().getPath() + "/";
//		logger.debug("1 classpath is: " + classPath);
//
//		if (classPath.indexOf("%20") != -1)
//			classPath = classPath.replaceAll("%20", " ");
//
//		/*
//		 * if(classPath.indexOf("home/actiz") == -1) { classPath =
//		 * classPath.substring(1); logger.debug("2 classpath is: " + classPath);
//		 * }
//		 */
//
//		// int i = classPath.indexOf("home/actiz");
//		// if(i != -1)
//		// {
//		// classPath = System.getenv("TOMCAT_HOME") + "/" +
//		// classPath.substring(i + 7);
//		// }
//
//		return classPath;
//	}
//
//	private String getClassPath1() {
//		return "E:/DESede/";
//	}

	public static void main(String[] args) throws Exception {
		System.out.println("come into");
		DesEncode de = new DesEncode();
		String password = "root";

		String encodeStr = de.encode(password, "E:/qyes/webapps/gzaic/WEB-INF/classes/jdbc.DESede");

		System.out.println("encodeStr is: " + encodeStr);

		String text = de.decode(encodeStr, "E:/qyes/webapps/gzaic/WEB-INF/classes/jdbc.DESede");

		System.out.println("text string is: " + text);

	}
}
